﻿using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using AVIS.OutBound.Cities;
using AVIS.OutBound.Stores.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVIS.OutBound.Stores
{
    /// <summary>
    /// 门店的应用服务类
    /// </summary>
    public class StoreAppService : OutBoundAppServiceBase, IStoreAppService
    {
        #region 构造函数
        private readonly IStoreManager _storeManger;
        private readonly IObjectMapper _objectMapper;
        private readonly IStoreRepository _storeRepository;

        /// <summary>
        /// 门店服务
        /// </summary>
        /// <param name="storeManger"></param>
        /// <param name="objectMapper"></param>
        /// <param name="storeRepository"></param>
        public StoreAppService(
            IStoreManager storeManger,
            IObjectMapper objectMapper,
            IStoreRepository storeRepository
            )
        {
            _storeManger = storeManger;
            _objectMapper = objectMapper;
            _storeRepository = storeRepository;
        }
        #endregion

        /// <summary>
        /// 获取指定城市的门店（包含附近门店）
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public List<StoreOutput> GetStoresByCity(GetStoresByCityInput input)
        {
            var stores = _storeManger.GetStoresByCity(input.cityCode, input.regionCode);
            var list = _objectMapper.Map<List<StoreOutput>>(stores);

            // 计算目的地的距离并排序
            if (input.DestLatitude != 0 && input.DestLongitude != 0)
            {
                foreach (var item in list)
                {
                    if (item.Latitude.HasValue && item.Longitude.HasValue)
                    {
                        item.Distance = GetDistance(input.DestLatitude, input.DestLongitude, item.Latitude.Value, item.Longitude.Value);
                    }
                    else
                    {
                        item.Distance = 0;
                    }
                }
                list = list.OrderBy(s => s.Distance).ToList();
            }

            return list;
        }


        /// <summary>
        /// 获取指定Code的门店信息
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public StoreOutput GetStoreByCode(GetStoreByCodeInput input)
        {
            var storeCacheItem = _storeManger.GetStoreByCode(input.storeCode);
            return _objectMapper.Map<StoreOutput>(storeCacheItem);
        }

        /// <summary>
        /// 搜索门店信息
        /// </summary>
        /// <param name="k">关键字，按中英名称或城市或地区进行查询</param>
        /// <returns></returns>
        public IList<StoreOutput> QueryStore(string k)
        {
            // 关键字必须超过两个字符
            var key = k.Trim();
            if (key.Length < 2)
            {
                return new List<StoreOutput>();
            }

            var queryData = _storeRepository.QueryStore(key);
            return _objectMapper.Map<List<StoreOutput>>(queryData);
        }

        #region 计算两个经纬度之间的距离
        private const double EARTH_RADIUS = 6378.137;//地球半径
        private double rad(double d)
        {
            return d * Math.PI / 180.0;
        }
        /*
         * 根据两点经纬度计算距离
         * 参考网址：http://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html
         */
        public double GetDistance(double lat1, double lng1, double lat2, double lng2)
        {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);

            double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
             Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.Round(s * 10000) / 10000;
            return s; //计算单位：公里  
        }
        #endregion
    }
}
